Conversation
* Fix asyncio event loop cleanup with SSO auth Previously, when applications using SSO authentication exited, the asyncio event loop was closed while background tasks were still running, resulting in: - ERROR: Task was destroyed but it is pending - RuntimeError: Event loop is closed This issue occurred specifically with SSO authentication flows that use push notifications, but not with password-only authentication. This fix ensures proper cleanup by: 1. Cancelling all pending tasks before stopping the event loop 2. Giving tasks time (0.3s) to handle CancelledError gracefully 3. Waiting for the event loop thread to finish before closing This prevents "Task was destroyed but it is pending" errors when shutting down applications that use SSO with push notifications. * Revert "Fix asyncio event loop cleanup with SSO auth" This reverts commit 8364e1c. * Close login websocket after authentication During SSO authentication flows, a push notification websocket (LoginPushNotifications) is created to handle 2FA, device approval, and SSO data key requests. This websocket was never closed after successful login, causing it to remain active until application shutdown. This resulted in asyncio errors about pending tasks being destroyed. Fix: Close login.push_notifications in _on_logged_in() immediately after authentication completes and before any post-login setup.
verify-records and verify-shared-folder commands added
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| else: | ||
| logger.info("User record belongs to another record.") | ||
|
|
||
| logger.info("") |
| logger.info("") | ||
|
|
||
| while True: | ||
| res = input(f"Does this user belong to {parent_record.title} Y/N >").lower() |
There was a problem hiding this comment.
create helper method yes/no checks Also support both 'y' and 'yes' as an input
| logger.error(f"The user record is not a PAM User.") | ||
| return | ||
|
|
||
| record_rotation = params.record_rotation_cache.get(user_record.record_uid) |
There was a problem hiding this comment.
pam action service add has a hard NameError: it reads params.record_rotation_cache, but the function argument is named context. That makes the command fail after record-type validation, so the new service-link flow is unusable.
| return None | ||
|
|
||
| gateway_context, payload = GatewayContext.find_gateway(vault=vault, | ||
| find_func=_find_job, |
There was a problem hiding this comment.
Discovery-by-job lookup is effectively dead code because GatewayContext.find_gateway() iterates an empty list. Both job status/preview and job removal call this helper, so they will never find a matching configuration even when the job exists.
Check line 78-83 in init.py
configuration_records=list()
|
|
||
| @staticmethod | ||
| def add_arguments_to_parser(parser: argparse.ArgumentParser): | ||
| choices = ['on', 'off', 'default'] |
There was a problem hiding this comment.
PAMConfigNewCommand parser destinations do not match what the implementation reads. The parser stores gateway and shared_folder, while the execution path expects gateway_uid and shared_folder_uid, so user-supplied values are ignored.
There was a problem hiding this comment.
parser.add_argument('--gateway', '-g', dest='gateway', action='store', help='Gateway UID or Name')
parser.add_argument('--shared-folder', '-sf', dest='shared_folder', action='store',
help='Share Folder where this PAM Configuration is stored. Should be one of the folders to '
'which the gateway has access to.')
|
|
||
| @staticmethod | ||
| def add_arguments_to_parser(parser: argparse.ArgumentParser): | ||
| choices = ['on', 'off', 'default'] |
There was a problem hiding this comment.
parser.add_argument('--gateway', '-g', dest='gateway', action='store', help='Gateway UID or Name')
parser.add_argument('--shared-folder', '-sf', dest='shared_folder', action='store',
help='Share Folder where this PAM Configuration is stored. Should be one of the folders to '
'which the gateway has access to.')
| value=item.get("value") | ||
| ) | ||
| ) | ||
|
|
There was a problem hiding this comment.
This method constructs Statement objects, but returns the raw statement_struct list instead. That breaks its own type contract and pushes raw parsed data into rule creation/update.
| logger.info(" * Changing the resource admin UID.") | ||
| rule_item.admin_uid = admin_uid | ||
|
|
||
| statement = kwargs.get("statement") |
There was a problem hiding this comment.
Rule update validates a new statement but never applies it to rule_item.statement. The CLI appears to succeed while silently doing nothing.
No description provided.